package com.exec;

import com.alibaba.fastjson.JSONObject;
import com.tycmc.util.RedisUtil;
import com.util.DateUtil;
import com.util.DruidUtil;
import com.util.PropertiesUtil;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import ty.pub.TransPacket;

import java.util.*;

public class OverSpeedController {

    /**
     * 超速报警
     *
     * @param inputObject
     * @return
     */
    public static String execOverSpeed(com.tycmc.bean.InputObject inputObject) {
        //判断inputObject中是否存在这个工况信息
        TransPacket transPacket = inputObject.getTransPacket();
        //获取基础数据
        Map<String, String> baseInfo = transPacket.getBaseInfoMap();
        //获取工况数据
        Map<String, Map<Long, String>> workStatusMap = transPacket.getWorkStatusMap();
        //信息生成时间工况编号
        String msgTimeNumber = PropertiesUtil.getStringPro("MsgTimeNumber");
        //获取信息生成时间
        long msgTime = MapUtils.getLong(baseInfo, msgTimeNumber);
        //获取超速工况编号
        String OverSpeed1Duty = PropertiesUtil.getStringPro("OverSpeed1");
        String OverSpeed2Duty = PropertiesUtil.getStringPro("OverSpeed2");
        String OverSpeed = PropertiesUtil.getStringPro("OverSpeed");
        //矿车速度工况编号
        String KCSpeed = PropertiesUtil.getStringPro("VclSpeed");
        //位置信息
        String VclPstn = PropertiesUtil.getStringPro("VclPstn");
        //获取设备ID
        String vclId = transPacket.getDeviceId();
        vclId = vclId.substring(4, vclId.length());
        //超速报警redis最新状态模板
        String NHLOverSpeedRedis = PropertiesUtil.getStringPro("NHLOverSpeed12");
        NHLOverSpeedRedis = NHLOverSpeedRedis.replaceAll("VCLID", vclId);
        Map<Long, String> Overspeed1Map = workStatusMap.get(OverSpeed1Duty);
        Map<Long, String> Overspeed2Map = workStatusMap.get(OverSpeed2Duty);
        Map<Long, String> KCSpeedMap = workStatusMap.get(KCSpeed);
        Map<Long, String> PstnMap = workStatusMap.get(VclPstn);
        Map<String, Object> mapLast = new HashMap<String, Object>();
        List<String> sqlList = new ArrayList<String>();
        if (MapUtils.isEmpty(Overspeed1Map)) {
            return null;
        }
        //获取信息生成时间数据集合
        Map<String,Object>mapStatic=inputObject.getCacheMap();
        String theVclmsgTime=MapUtils.getString(mapStatic,vclId+"_"+OverSpeed);
        //如果为空，直接存入缓存map中
        if(StringUtils.isBlank(theVclmsgTime)){
            mapStatic.put(vclId+"_"+OverSpeed,DateUtil.getStrTime(msgTime,0));
            sqlList.add(" insert into  CacheKZExecTable(CKZET_VclId,CKZET_LastMsgTime,CKZET_InsertTime,CKZET_Type)values('"+vclId+"','"+DateUtil.getStrTime(msgTime,0)+"',now(),"+OverSpeed+")  " +
                    "ON DUPLICATE KEY UPDATE CKZET_LastMsgTime='"+DateUtil.getStrTime(msgTime,0)+"',CKZET_InsertTime=now()");
        }else{//如果不为空
            //上下时间比较
            long lastVclmsgTime=Long.valueOf(DateUtil.getLongTime(theVclmsgTime));
            if(msgTime>=lastVclmsgTime){
                mapStatic.put(vclId+"_"+OverSpeed,DateUtil.getStrTime(msgTime,0));
                sqlList.add(" insert into  CacheKZExecTable(CKZET_VclId,CKZET_LastMsgTime,CKZET_InsertTime,CKZET_Type)values('"+vclId+"','"+DateUtil.getStrTime(msgTime,0)+"',now(),"+OverSpeed+")  " +
                        "ON DUPLICATE KEY UPDATE CKZET_LastMsgTime='"+DateUtil.getStrTime(msgTime,0)+"',CKZET_InsertTime=now()");
            }else{
                //缓存数据
                return null;
            }
        }
        //将超速1和超速2两个集合合并
        Set<Long>speedSet1=keySet(Overspeed1Map);
        if(Overspeed2Map!=null&&Overspeed2Map.size()>0){
            Set<Long>speedSet2=keySet(Overspeed2Map);
            speedSet1.addAll(speedSet2);
            for(long key:speedSet1){
                String overSpeedState1=MapUtils.getString(Overspeed1Map,key);
                String overSpeedState2=MapUtils.getString(Overspeed2Map,key);
                if("1".equals(overSpeedState1)||"1".equals(overSpeedState2)){
                    Overspeed1Map.put(key,"1");
                }else{
                    Overspeed1Map.put(key,"0");
                }
            }
        }

        for (long key : Overspeed1Map.keySet()) {
            boolean isOver = false;
            //参数采集时间
            String msgtimeGet = DateUtil.getStrTime(msgTime, key);
            //首先判断map
            String overSpeedV = MapUtils.getString(Overspeed1Map, key);
            //String overSpeed2V=MapUtils.getString(Overspeed2Map,key);
            String MsgOS_Speed;
            if (MapUtils.isEmpty(KCSpeedMap)) {
                MsgOS_Speed = null;
            } else {
                //获取距离key时间最近的一条速度值
                MsgOS_Speed=getMinSpeed(KCSpeedMap, key);
            }
            String Lo;
            String La;
            if (MapUtils.isEmpty(PstnMap)) {
                Lo = null;
                La = null;
            } else {

                String pstnStr =getLastPstn(PstnMap, key);
                if (StringUtils.isBlank(pstnStr)) {
                    Lo = null;
                    La = null;
                } else {
                    JSONObject jobpstn = JSONObject.parseObject(pstnStr);
                    Lo = MapUtils.getString(jobpstn, "Lo");
                    La = MapUtils.getString(jobpstn, "La");
                }

            }

            if ("1".equals(overSpeedV)) {
                isOver = true;
            }
            if (MapUtils.isNotEmpty(mapLast)) {//Map不为空
                //获取redis中此设备的状态
                String MsgOS_BgnTime = MapUtils.getString(mapLast, "MsgOS_BgnTime");
                String MsgOS_EndTime = MapUtils.getString(mapLast, "MsgOS_EndTime");
                if (StringUtils.isNotBlank(MsgOS_BgnTime) && StringUtils.isNotBlank(MsgOS_EndTime)) {//如果都不为空，说明当前超速解除状态
                    if (isOver) {//超速，状态与上述不同
                        //存储当前状态
                        String pstnStr = MapUtils.getString(PstnMap, key);
                        JSONObject jo = JSONObject.parseObject(pstnStr);
                        mapLast.put("MsgOS_Vcl_ID", vclId);
                        mapLast.put("MsgOS_BgnTime", msgtimeGet);
                        mapLast.put("MsgOS_Speed", MapUtils.getString(KCSpeedMap, key));
                        mapLast.put("MsgOS_lng", MapUtils.getString(jo, "Lo"));
                        mapLast.put("MsgOS_lat", MapUtils.getString(jo, "La"));
                        mapLast.put("MsgOS_EndTime", "");
                        //表中插入一条数据
                        sqlList.add("insert into Msg_OverSpeed_" + msgtimeGet.substring(0, 7).replaceAll("-", "") + "(MsgOS_Vcl_ID,MsgOS_BgnTime,MsgOS_Speed,MsgOS_lng,MsgOS_lat)values(" + vclId + ",'" + msgtimeGet + "'," + MsgOS_Speed + "," + Lo + "," + La + ")");
                    }
                } else if (StringUtils.isNotBlank(MsgOS_BgnTime) && StringUtils.isBlank(MsgOS_EndTime)) { //当前是报警
                    if (!isOver) {//解除状态
                        List<Object> redisValueLast = RedisUtil.hgetWithpip(NHLOverSpeedRedis, "MsgOS_BgnTime", "MsgOS_Speed", "MsgOS_lng", "MsgOS_lat");
                        int i = 0;
                        String _MsgOS_BgnTime = MapUtils.getString(mapLast, "MsgOS_BgnTime");
                        String _MsgOS_Speed = MapUtils.getString(mapLast, "MsgOS_Speed");
                        String _MsgOS_lng = MapUtils.getString(mapLast, "MsgOS_lng");
                        String _MsgOS_lat = MapUtils.getString(mapLast, "MsgOS_lat");
                        mapLast.put("MsgOS_Vcl_ID", vclId);
                        mapLast.put("MsgOS_BgnTime", _MsgOS_BgnTime);
                        mapLast.put("MsgOS_Speed", _MsgOS_Speed);
                        mapLast.put("MsgOS_lng", _MsgOS_lng);
                        mapLast.put("MsgOS_lat", _MsgOS_lat);
                        mapLast.put("MsgOS_EndTime", msgtimeGet);
                        sqlList.add("update Msg_OverSpeed_" + msgtimeGet.substring(0, 7).replaceAll("-", "") + " set MsgOS_EndTime='" + msgtimeGet + "' where MsgOS_Vcl_ID=" + vclId + " and MsgOS_EndTime is null");
                    }
                }
            } else {
                //获取redis中此设备的状态
                String MsgOS_EndTime = RedisUtil.hget(NHLOverSpeedRedis, "MsgOS_EndTime");
                String MsgOS_BgnTime = RedisUtil.hget(NHLOverSpeedRedis, "MsgOS_BgnTime");
                if (StringUtils.isNotBlank(MsgOS_BgnTime) && StringUtils.isNotBlank(MsgOS_EndTime)) {//如果都不为空，说明当前超速解除状态
                    if (isOver) {//超速，状态与上述不同
                        //存储当前状态
                        String pstnStr = MapUtils.getString(PstnMap, key);
                        JSONObject jo = JSONObject.parseObject(pstnStr);
                        mapLast.put("MsgOS_Vcl_ID", vclId);
                        mapLast.put("MsgOS_BgnTime", msgtimeGet);
                        mapLast.put("MsgOS_Speed", MsgOS_Speed);
                        mapLast.put("MsgOS_lng", MapUtils.getString(jo, "Lo"));
                        mapLast.put("MsgOS_lat", MapUtils.getString(jo, "La"));
                        mapLast.put("MsgOS_EndTime", "");
                        //表中插入一条数据
                        sqlList.add("insert into Msg_OverSpeed_" + msgtimeGet.substring(0, 7).replaceAll("-", "") + "(MsgOS_Vcl_ID,MsgOS_BgnTime,MsgOS_Speed,MsgOS_lng,MsgOS_lat)values(" + vclId + ",'" + msgtimeGet + "'," + MsgOS_Speed + "," + Lo + "," + La + ")");
                    }
                } else if (StringUtils.isNotBlank(MsgOS_BgnTime) && StringUtils.isBlank(MsgOS_EndTime)) {//报警状态
                    if (!isOver) {//解除状态
                        List<Object> redisValueLast = RedisUtil.hgetWithpip(NHLOverSpeedRedis, "MsgOS_BgnTime", "MsgOS_Speed", "MsgOS_lng", "MsgOS_lat");
                        int i = 0;
                        String _MsgOS_BgnTime = redisValueLast.get(i) == null ? null : String.valueOf(redisValueLast.get(i));
                        i++;
                        String _MsgOS_Speed = redisValueLast.get(i) == null ? null : String.valueOf(redisValueLast.get(i));
                        i++;
                        String _MsgOS_lng = redisValueLast.get(i) == null ? null : String.valueOf(redisValueLast.get(i));
                        i++;
                        String _MsgOS_lat = redisValueLast.get(i) == null ? null : String.valueOf(redisValueLast.get(i));

                        mapLast.put("MsgOS_Vcl_ID", vclId);
                        mapLast.put("MsgOS_BgnTime", _MsgOS_BgnTime);
                        mapLast.put("MsgOS_Speed", _MsgOS_Speed);
                        mapLast.put("MsgOS_lng", _MsgOS_lng);
                        mapLast.put("MsgOS_lat", _MsgOS_lat);
                        mapLast.put("MsgOS_EndTime", msgtimeGet);
                        sqlList.add("update Msg_OverSpeed_" + msgtimeGet.substring(0, 7).replaceAll("-", "") + " set MsgOS_EndTime='" + msgtimeGet + "' where MsgOS_Vcl_ID=" + vclId + " and MsgOS_EndTime is null");
                    }
                } else {
                    if (isOver) {//超速才会处理
                        //存储当前状态
                        String pstnStr = MapUtils.getString(PstnMap, key);
                        JSONObject jo = JSONObject.parseObject(pstnStr);
                        mapLast.put("MsgOS_Vcl_ID", vclId);
                        mapLast.put("MsgOS_BgnTime", msgtimeGet);
                        mapLast.put("MsgOS_Speed", MsgOS_Speed);
                        mapLast.put("MsgOS_lng", Lo);
                        mapLast.put("MsgOS_lat", La);
                        mapLast.put("MsgOS_EndTime", "");
                        //表中插入一条数据
                        sqlList.add("insert into Msg_OverSpeed_" + msgtimeGet.substring(0, 7).replaceAll("-", "") + "(MsgOS_Vcl_ID,MsgOS_BgnTime,MsgOS_Speed,MsgOS_lng,MsgOS_lat)values(" + vclId + ",'" + msgtimeGet + "'," + MsgOS_Speed + "," + Lo + "," + La + ")");
                    }
                }
            }
        }
        if (mapLast.size() > 0) {
            RedisUtil.hsetWithpip(NHLOverSpeedRedis, mapLast);
        }
        if (sqlList.size() > 0) {
            DruidUtil.batch(sqlList);
        }
        return null;
    }

    //将Map的key转成set集合
    public static Set<Long> keySet(Map<Long, String> map) {
        Set<Long> set = new HashSet<Long>();
        Set<Long> mapSet = map.keySet();
        for (long key : mapSet) {
            set.add(key);
        }
        return set;
    }
    //获取最近的速度
    public static String getMinSpeed(Map<Long, String> map,long value) {
        Set<Long> mapSet = map.keySet();
        long keymin=-1;
        long timeDeff=-1;
        for (long key : mapSet) {
            long deff=Math.abs(value-key);
            if(timeDeff==-1){
                timeDeff=deff;
                keymin=key;
            }else if(deff<timeDeff){
                timeDeff=deff;
                keymin=key;
            }
        }
        String speed=MapUtils.getString(map,keymin);
        return speed;
    }
    //获取最近的经纬度
    public static String getLastPstn(Map<Long, String> mapPstn,long value) {
        Set<Long> mapSet = mapPstn.keySet();
        long keymin=-1;
        long timeDeff=-1;
        for (long key : mapSet) {
            long deff=Math.abs(value-key);
            if(timeDeff==-1){
                timeDeff=deff;
                keymin=key;
            }else if(deff<timeDeff){
                timeDeff=deff;
                keymin=key;
            }
        }
        String speed=MapUtils.getString(mapPstn,keymin);
        return speed;
    }
}